<template>
  <a-card style="height: 100%" :bodyStyle="{padding:'10px',height:'100%',display:'flex',flexDirection:'column'}">
    <a-space v-if="!hideTools" style="margin-bottom: 10px" :size="10">
      <render v-if="!hideAdd" :data="tools.add"></render>
      <a-button shape="circle" size="small" @click="loadData">
        <template #icon>
          <reload-outlined/>
        </template>
      </a-button>
    </a-space>
    <a-input v-if="!hideFilter" v-model:value="searchValue" style="margin-bottom: 8px">
      <template #prefix>
        <search-outlined style="color: #c0c4cc;" />
      </template>
    </a-input>
    <div  class="ex_scrollbar">
      <a-tree
          :expanded-keys="expandedKeys"
          :tree-data="treeData"
          :auto-expand-parent="autoExpandParent"
          :fieldNames="fieldNames"
          @expand="onExpand"
          @select="onSelect"
          @mouseenter="onMouseenter"
          @mouseleave="onMouseleave"
          block-node
          v-model:selectedKeys="selectedKeys"
      >
        <template #title="item">
        <span v-if="searchValue && item[title] && item[title].indexOf(searchValue) > -1" class="flex">
          <span>
          {{ item[title].substr(0, item[title].indexOf(searchValue)) }}
          <span style="color: #f50">{{ searchValue }}</span>
          {{ item[title].substr(item[title].indexOf(searchValue) + searchValue.length) }}
          </span>
           <span class="action" v-if="mouseenterIndex == item[keyName] && (item.ex_admin_edit || item.ex_admin_delete)">
              <render v-if="!hideEdit" :data="item.ex_admin_edit"></render>
              <render v-if="!hideDel" :data="item.ex_admin_delete" @success="loadData"></render>
            </span>
        </span>
          <span v-else class="flex">
            <render :data="item['ex_admin_render']"></render>
            <span class="action" v-if="mouseenterIndex == item[keyName] && (item.ex_admin_edit || item.ex_admin_delete)">
              <render v-if="!hideEdit" :data="item.ex_admin_edit"></render>
              <render v-if="!hideDel" :data="item.ex_admin_delete" @success="loadData"></render>
            </span>
          </span>
        </template>
      </a-tree>
    </div>

  </a-card>
</template>

<script>
export default {
  name: "ExSidebar",
  inheritAttrs:false
}
</script>
<script setup>
import useHttp from '@/hook/use-http'
import {treeArray,trans} from "@/utils";
import {ref,watch} from 'vue'
import bus from "@/store/bus";
const {loading, http} = useHttp()
const props = defineProps({
  hideAll: Boolean,
  hideAdd: Boolean,
  hideEdit: Boolean,
  hideDel: Boolean,
  hideFilter: Boolean,
  hideTools: Boolean,
  isTree: Boolean,
  tools: [Object, Boolean],
  value:[String, Number],
  sourceList :{
    type: Array,
    default:[],
  },
  default: {
    type:  [String, Number],
    default:undefined,
  },
  field: {
    type: String,
    default:'group_id',
  },
  selectedField:String,
  fieldNames:Object,
  url: String,
  params: {
    type: Object,
    default: {},
  },
})
const emit = defineEmits(['update:value'])
let parentKey,children = props.fieldNames.children,keyName=props.fieldNames.key,title=props.fieldNames.title;
if(props.default !== undefined){
  emit('update:value',props.default)
}
const selectedKeys = ref([props.default])
const searchValue = ref('')
const mouseenterIndex = ref(-1)
const expandedKeys = ref(props.sourceList.map((item) => {
  return item[keyName]
}))
const autoExpandParent = ref(true)
const treeData = ref(getData(props.sourceList))

const getParentKey = (key,tree) => {

  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node[children]) {
      if (node[children].some(item => item[keyName] === key)) {
        parentKey = node[keyName];
      } else if (getParentKey(key, node[children])) {
        parentKey = getParentKey(key, node[children]);
      }
    }
  }
  return parentKey;
};
const onExpand = (keys) => {
  expandedKeys.value = keys;
  autoExpandParent.value = false;
};

watch(searchValue, value => {
  expandedKeys.value = props.sourceList.map((item) => {
    if (item[title].indexOf(value) > -1) {

      return getParentKey(item[keyName], treeData.value);
    }
    return null;
  })
      .filter((item, i, self) => item && self.indexOf(item) === i);
  searchValue.value = value;
  autoExpandParent.value = true
});
const onSelect  = (selectedKeys,e)=>{
  if(e.selected){
    const id = selectedKeys[0]

    if(props.selectedField){
      emit('update:value', e.node[props.selectedField])
    }else{
      emit('update:value',id)
    }
  }else{
    emit('update:value',null)
  }
}
function getData(data) {
  if(props.isTree){
    data =  treeArray(data, keyName, props.fieldNames.pid, children)
  }
  if(data.length == 0){
    selectedKeys.value = ['']
    emit('update:value','')
  }
  if(!props.hideAll){
    const all = {}
    all[keyName] = ''
    all[title] = trans('Sidebar.all')
    all['ex_admin_render'] = {
      name:'html',
      attribute:{
        'data-tag':'span'
      },
      content:{
        default:[all[title]]
      }
    }
    data.unshift(all)
  }
  return data
}
bus.on(event=>{
  if(event == 'Success'){
    loadData()
  }
})
function loadData(){
  http({
    url:props.url,
    method:'post',
    data:props.params,
  }).then(result=>{
    treeData.value = getData(result)
  })
}
function onMouseenter(e){
  let id = e.node[keyName]
  if(id){
    mouseenterIndex.value = id
  }
}
function onMouseleave(){
  mouseenterIndex.value = -1
}
</script>
<style scoped>
.flex{
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
}
.action{
  margin-left: 10px;
}
</style>
